Skip to content
开发研究OpenTimestamps

给想法做时间戳:我的 Proof Ledger 工作流

记录一套用 SHA-256、OpenTimestamps、Git 和 GPG 给研究笔记与 idea draft 做时间戳的轻量 Proof Ledger 工作流。

2026-06-10 13:49:101,812 字5 分钟阅读

最近我开始给自己的研究笔记和 idea draft 做时间戳。

起因很简单:我经常会在刚接触一个领域之后,快速想到一些问题、方法和实验设计。后来过几周、几个月,甚至几天,在 arXiv 或顶会论文里看到相近的路线。这种情况发生多了之后,我意识到单纯说“我之前也想过”没有什么意义。真正有用的是留下一条可验证的时间线:某个想法、某个草稿、某个实验计划,确实在某个时间点之前已经存在。

这件事听起来像“防抄袭”,但对我来说更像研究卫生习惯。写下想法、固定版本、留下哈希、生成时间戳证明。以后回看时,我能清楚知道一个 idea 是什么时候形成的、当时理解到了哪一步、后面有没有被新的工作 scoop、自己的判断和社区前沿差了多远。

核心思路

我采用的方案很简单:

text
private note
→ SHA-256 digest
→ OpenTimestamps proof
→ public proof ledger

完整的 idea note 保留在私有仓库里。公开页面只展示它的 SHA-256 哈希值和 OpenTimestamps 证明文件。

这样可以同时满足两个目标:

  1. 保密:公开页面不会泄露 note 的具体内容。
  2. 可验证:未来公开原文时,任何人都可以重新计算 SHA-256,并和当时发布的 digest 对比。

如果 digest 一致,就说明公开的原文和当年存证的内容完全相同。OpenTimestamps 则证明这个 digest 文件在某个时间点之前已经存在。

这是一种很轻量的 commitment:我承诺了某份内容,但我暂时保留内容本身。

为什么选择哈希,而不是直接公开原文

研究想法在早期通常很脆弱。很多 idea 只是一段观察、一个方法草图、一组实验设计,公开太早会泄露路线,也会增加沟通成本。

哈希值正好解决这个问题。

对一份文档计算 SHA-256,会得到一个 64 位十六进制字符串。这个字符串几乎可以看作这份文档的指纹。文档里哪怕只改一个字符,哈希值也会完全变化。

所以我公开的是:

text
SHA-256(note)

完整 note 仍然私有保存。未来需要证明时,拿出 note 重新计算哈希,对上公开 digest 即可。

Git 签名

除了 OTS,我也会用 GPG 签名 Git commit 和 tag。

这一步解决的是“这个记录来自谁”的问题。OTS 证明时间,GPG 绑定身份,Git 保留版本历史。三者组合起来,证据链会清楚很多。

基础配置大概是:

bash
git config --global user.name "Your Name"
git config --global user.email "your-email@example.com"
git config --global user.signingkey <your-gpg-fingerprint>
git config --global commit.gpgsign true
git config --global tag.gpgSign true

提交:

bash
git add notes/ proofs/
git commit -S -m "idea: adaptive probe"

Git commit 记录文档版本,GPG signature 表示这次提交由我的密钥签名,OTS proof 证明 digest 在某个时间点前已经存在。

每次 commit 自动生成 digest

shell
#!/usr/bin/env bash
set -euo pipefail

usage() {
  cat <<'EOF'
usage: scripts/auto-commit.sh [--print-message]

Stage all changes, generate a simple commit message from changed paths, and commit.
EOF
}

mode="commit"
case "${1:-}" in
  -h|--help)
    usage
    exit 0
    ;;
  --print-message)
    mode="print"
    ;;
  "")
    ;;
  *)
    printf 'unexpected argument: %s\n' "$1" >&2
    usage >&2
    exit 2
    ;;
esac

git rev-parse --is-inside-work-tree >/dev/null
git add -A

if git diff --cached --quiet; then
  if [ "$mode" = "print" ]; then
    printf 'chore: no changes\n'
  else
    printf 'nothing to commit\n'
  fi
  exit 0
fi

paths="$(git diff --cached --name-only)"

all_match() {
  local pattern="$1"
  local path

  while IFS= read -r path; do
    [ -n "$path" ] || continue
    case "$path" in
      $pattern) ;;
      *) return 1 ;;
    esac
  done <<EOF
$paths
EOF
}

any_match() {
  local pattern="$1"
  local path

  while IFS= read -r path; do
    [ -n "$path" ] || continue
    case "$path" in
      $pattern) return 0 ;;
    esac
  done <<EOF
$paths
EOF
  return 1
}

first_path="$(printf '%s\n' "$paths" | sed -n '1p')"
message="chore: update project"

if all_match "notes/*.md"; then
  count="$(printf '%s\n' "$paths" | grep -c .)"
  if [ "$count" -eq 1 ]; then
    slug="$(basename "$first_path" .md)"
    message="note: update $slug"
  else
    message="note: update notes"
  fi
elif all_match "proofs/*"; then
  message="proof: update timestamp proofs"
elif all_match "README.md" || all_match "statusquo.md" || all_match "docs/*"; then
  message="docs: update docs"
elif all_match "tests/*"; then
  message="test: update tests"
elif any_match "scripts/*" || any_match "justfile" || any_match ".githooks/*"; then
  message="chore: update tooling"
elif any_match "README.md" || any_match "statusquo.md" || any_match "docs/*"; then
  message="docs: update project docs"
fi

if [ "$mode" = "print" ]; then
  printf '%s\n' "$message"
  exit 0
fi

printf 'commit: %s\n' "$message"
git commit --no-gpg-sign -m "$message"

博客上的 Proof Ledger

Ledger

验证方式

验证 OTS:

bash
ots verify 20260609T173012Z-a1b2c3d4.sha256.ots

未来如果原始 note 公开,可以重新计算哈希:

bash
sha256sum adaptive-probe.md

然后和公开的 .sha256 文件比较:

bash
cat 20260609T173012Z-a1b2c3d4.sha256

如果一致,说明这份公开 note 就是当时 digest 对应的那份文档。

完整链路是:

text
original note
→ SHA-256 digest
→ published .sha256 file
→ .sha256.ots timestamp proof
→ public verification

这套系统的结果

完成后,我得到的是一个很轻的研究存证系统:

text
Markdown 写 note
Git 管版本
GPG 签名身份
SHA-256 固定内容
OpenTimestamps 固定时间
博客 Proof Ledger 做公开展示

它没有复杂后台,没有数据库,没有重型平台,也没有多余字段。每个证明条目只依赖几个非常基础的东西:文本文件、哈希、Git、GPG、OTS。

这套系统带来的实际效果很明显:

  • 我可以稳定记录 idea 的形成时间。
  • 我可以公开证明某份内容在某个时间点前已经存在。
  • 我可以保留完整 note 的私密性。
  • 我可以把研究轨迹从“口头回忆”变成“可验证记录”。
  • 我可以在必要时拿出更早的私有草稿、signed commit 或 proof 文件补全证据链。

它也会反向约束我自己。一个 idea 值不值得存证,取决于我能不能把它写成清楚的 problem、core insight、method sketch 和 expected experiment。很多模糊想法在这个过程中会自然消失,留下来的通常更像真正的研究资产。

目的

这套 ledger 的目的很克制:记录 prior existence。

对我来说,这已经足够有价值。

研究里最难受的事情之一,是自己确实提前想到了某条路线,却没有留下任何可验证记录。Proof Ledger 解决的就是这个问题。它把直觉、草稿、实验计划、技术判断,变成一条可审计的时间线。

以后我再看到相近工作时,可以更冷静地比较:我当时想到的是同一个问题,还是同一个方法?实验设计是否接近?我漏掉了什么?我的下一步差异化空间在哪里?

这比单纯感叹“我也想过”有用得多。

Last updated: